﻿using System.Linq;

namespace Sidvall.Data
{
    public class DataRowStateCountItemCollection : System.Collections.ObjectModel.KeyedCollection<string, DataRowStateCountItem>
    {
        #region Public Members

        #region Add

        public void Add(string resource)
        {
            GetItem(resource);
        }
        public void Add(string resource, IDataRowContextProvider item)
        {
            if (item == null)
                return;
            if (item.DataRowStateIsDeleted)
                Add(resource, 0, 0, 0, 1);
            else if (item.DataRowStateIsNew)
                Add(resource, 0, 0, 1, 0);
            else if (item.DataRowStateIsSelfDirty)
                Add(resource, 0, 1, 0, 0);
            else
                Add(resource, 1, 0, 0, 0);
        }
        public void Add(string resource, IListContextProvider item)
        {
            if (item == null)
                return;
            Add(resource, 0, 0, 0, item.DeletedItemKeys.Count());
        }
        public void Add(string resource, int unchangedCount, int modifiedCount, int addedCount, int deletedCount)
        {
            var item = GetItem(resource);
            if (item == null)
                return;
            item.UnchangedCount += unchangedCount;
            item.ModifiedCount += modifiedCount;
            item.AddedCount += addedCount;
            item.DeletedCount += deletedCount;
        }

        #endregion
        #region GetDescription

        public string GetDescription(string addedCountFormat, string modifiedCountFormat, string deletedCountFormat, string unchangedCountFormat)
        {
            return GetDescription(addedCountFormat, modifiedCountFormat, deletedCountFormat, unchangedCountFormat, null);
        }
        public string GetDescription(string addedCountFormat, string modifiedCountFormat, string deletedCountFormat, string unchangedCountFormat,
            System.Func<string, string> getResourceNameHandler)
        {
            return GetDescription(addedCountFormat, modifiedCountFormat, deletedCountFormat, unchangedCountFormat, getResourceNameHandler, "{0}: {1}",
                System.Environment.NewLine + System.Environment.NewLine, ", ");
        }
        public string GetDescription(string addedCountFormat, string modifiedCountFormat, string deletedCountFormat, string unchangedCountFormat,
            System.Func<string, string> getResourceNameHandler, string resourceFormat, string resourceSeparator, string countSeparator)
        {
            System.Text.StringBuilder sb;
            string itemValue, resource;

            sb = new System.Text.StringBuilder();
            foreach (var item in this)
            {
                itemValue = string.Empty;
                if ((!string.IsNullOrWhiteSpace(addedCountFormat)) && (item.AddedCount > 0))
                {
                    if (!string.IsNullOrWhiteSpace(itemValue))
                        itemValue += countSeparator;
                    itemValue += string.Format(System.Globalization.CultureInfo.CurrentCulture, addedCountFormat, item.AddedCount.ToString(System.Globalization.CultureInfo.CurrentCulture));
                }
                if ((!string.IsNullOrWhiteSpace(modifiedCountFormat)) && (item.ModifiedCount > 0))
                {
                    if (!string.IsNullOrWhiteSpace(itemValue))
                        itemValue += countSeparator;
                    itemValue += string.Format(System.Globalization.CultureInfo.CurrentCulture, modifiedCountFormat, item.ModifiedCount.ToString(System.Globalization.CultureInfo.CurrentCulture));
                }
                if ((!string.IsNullOrWhiteSpace(deletedCountFormat)) && (item.DeletedCount > 0))
                {
                    if (!string.IsNullOrWhiteSpace(itemValue))
                        itemValue += countSeparator;
                    itemValue += string.Format(System.Globalization.CultureInfo.CurrentCulture, deletedCountFormat, item.DeletedCount.ToString(System.Globalization.CultureInfo.CurrentCulture));
                }
                if ((!string.IsNullOrWhiteSpace(unchangedCountFormat)) && (item.UnchangedCount > 0))
                {
                    if (!string.IsNullOrWhiteSpace(itemValue))
                        itemValue += countSeparator;
                    itemValue += string.Format(System.Globalization.CultureInfo.CurrentCulture, unchangedCountFormat, item.UnchangedCount.ToString(System.Globalization.CultureInfo.CurrentCulture));
                }
                if (!string.IsNullOrWhiteSpace(itemValue))
                {
                    if (sb.Length > 0)
                        sb.Append(resourceSeparator);
                    if (getResourceNameHandler != null)
                        resource = getResourceNameHandler(item.Resource);
                    else
                        resource = item.Resource;
                    sb.Append(string.Format(System.Globalization.CultureInfo.CurrentCulture, resourceFormat, resource, itemValue));
                }
            }
            return sb.ToString();
        }

        #endregion
        #region GetItem

        public DataRowStateCountItem GetItem(string resource)
        {
            if (string.IsNullOrWhiteSpace(resource))
                return null;
            if (!Contains(resource))
            {
                var item = new DataRowStateCountItem()
                {
                    Resource = resource,
                };
                Add(item);
                return item;
            }
            else
            {
                return this[resource];
            }
        }

        #endregion
        #region GetKeyForItem

        protected override string GetKeyForItem(DataRowStateCountItem item)
        {
            if (item == null)
                throw new System.ArgumentNullException(nameof(item));
            return item.Resource;
        }

        #endregion

        #endregion
        #region Constructors

        public DataRowStateCountItemCollection()
            : base(System.StringComparer.OrdinalIgnoreCase)
        {
        }

        #endregion
    }
}
